/**
 * 
 */
package com.dalonedrow.engine.ui.base.border;

import com.dalonedrow.engine.sprite.base.SimpleVector3;
import com.dalonedrow.engine.sprite.base.SpriteBase;
import com.dalonedrow.engine.sprite.base.SpriteImageObject;
import com.dalonedrow.engine.sprite.base.SpriteImageObjectFactory;
import com.dalonedrow.engine.sprite.impl.BasicQuadSpriteObject;
import com.dalonedrow.engine.sprite.impl.BasicSpriteObject;
import com.dalonedrow.engine.sprite.impl.GroupOfImages;
import com.dalonedrow.engine.systems.JOGLErrorHandler;
import com.dalonedrow.engine.systems.Render;
import com.dalonedrow.engine.systems.Sprite;
import com.dalonedrow.globalvariables.constants.hq.GlobalConstants;

/**
 * Abstract class for implementing ui borders comprised of 8 images and an RGBA
 * background.
 * @author DaLoneDrau
 */
public class Abstract8x4ImageBorder extends GuiBorder {
	/** the border group. */
	private GroupOfImages			borders;
	/** the middle sprite. */
	private BasicQuadSpriteObject	middle;
	/** the middle images group. */
	private GroupOfImages			middleImages;
	/** the x-offset for the middle graphic. */
	private int						middleInsetX;
	/** the y-offset for the middle graphic. */
	private int						middleInsetY;
	/**
	 * flag indicating whether supplied offsets are used for middle background.
	 */
	private boolean					useOffsets;
	/**
	 * Creates a new instance of {@link Abstract8x4ImageBorder}.
	 * @param insets the border insets
	 * @param corners the corner images
	 * @param middleSet the background images
	 * @param middleColor the background color
	 */
	Abstract8x4ImageBorder(final int[] insets, final String[] corners,
			final String[] middleSet, final float[] middleColor) {
		this(insets, corners, middleSet, middleColor, 0, 0);
	}
	/**
	 * Creates a new instance of {@link Abstract8x4ImageBorder}.
	 * @param insets the border insets
	 * @param corners the corner images
	 * @param middleSet the background images
	 * @param background the background color
	 * @param xOffset the x-offset for the middle background
	 * @param yOffset the y-offset for the middle background
	 */
	Abstract8x4ImageBorder(final int[] insets, final String[] corners,
			final String[] middleSet, final float[] background,
			final int xOffset, final int yOffset) {
		if (insets == null
				|| insets != null
				&& insets.length != GlobalConstants.INT_004) {
			super.setInsets(
					GlobalConstants.INT_008,
					GlobalConstants.INT_008,
					GlobalConstants.INT_008,
					GlobalConstants.INT_008
					);
		} else {
			super.setInsets(insets);
		}
		if (middleSet == null
				|| middleSet != null
				&& middleSet.length != GlobalConstants.INT_008) {
			JOGLErrorHandler.getInstance().fatalError(new Exception(
					"At least 8 images are needed for the middle background."));
		}
		if (corners == null
				|| corners != null
				&& corners.length != GlobalConstants.INT_008) {
			JOGLErrorHandler.getInstance().fatalError(new Exception(
					"At least 8 images are needed for the borders."));
		}
		if (background == null
				|| background != null
				&& (background.length < GlobalConstants.INT_003
				|| background.length > GlobalConstants.INT_004)) {
			JOGLErrorHandler.getInstance().fatalError(new Exception(
					"3 or 4-color background is needed."));
		}
		middleInsetX = xOffset;
		middleInsetY = yOffset;
		try {
			setBorders(corners);
			setMiddleImages(middleSet);
			// sprite images don't get set until the preferred size is set
			if (middleInsetX != -1
					&& middleInsetY != -1) {
				useOffsets = true;
			}
			SpriteImageObject img =
					SpriteImageObjectFactory.getInstance().getImageByName(
							corners[GlobalConstants.CORNER_03LEFT]);
			if (middleInsetX == -1) {
				middleInsetX = img.getWidth();
			}
			img = SpriteImageObjectFactory.getInstance().getImageByName(
					corners[GlobalConstants.CORNER_01BOTTOM]);
			if (middleInsetY == -1) {
				middleInsetY = img.getHeight();
			}
			// middle
			middle = new BasicQuadSpriteObject();
			middle.setRed(background[0]);
			middle.setGreen(background[1]);
			middle.setBlue(background[2]);
			if (background.length == GlobalConstants.INT_003) {
				middle.setAlpha(1);
			} else {
				middle.setAlpha(background[GlobalConstants.INT_003]);
			}
		} catch (Exception ex) {
			JOGLErrorHandler.getInstance().fatalError(ex);
		}
	}
	/**
	 * Positions all border pieces.
	 * @param width the border width
	 * @param height the border height
	 * @throws Exception if an error occurs
	 */
	private void positionBorders(final int width, final int height)
			throws Exception {
		// get images
		SpriteImageObject imgBL =
				SpriteImageObjectFactory.getInstance().getImageById(
						borders.getImage(
								GlobalConstants.CORNER_00BOTTOM_LEFT)
								.getImageRefId()
						);
		SpriteImageObject imgBR =
				SpriteImageObjectFactory.getInstance().getImageById(
						borders.getImage(
								GlobalConstants.CORNER_02BOTTOM_RIGHT)
								.getImageRefId()
						);
		SpriteImageObject imgR =
				SpriteImageObjectFactory.getInstance().getImageById(
						borders.getImage(
								GlobalConstants.CORNER_04RIGHT)
								.getImageRefId()
						);
		SpriteImageObject imgTL =
				SpriteImageObjectFactory.getInstance().getImageById(
						borders.getImage(
								GlobalConstants.CORNER_05TOP_LEFT)
								.getImageRefId()
						);
		SpriteImageObject imgT =
				SpriteImageObjectFactory.getInstance().getImageById(
						borders.getImage(
								GlobalConstants.CORNER_06TOP)
								.getImageRefId()
						);
		SpriteImageObject imgTR =
				SpriteImageObjectFactory.getInstance().getImageById(
						borders.getImage(
								GlobalConstants.CORNER_07TOP_RIGHT)
								.getImageRefId()
						);
		// set bottom-left position
		borders.getImage(GlobalConstants.CORNER_00BOTTOM_LEFT).setPosition(
				new SimpleVector3(0, 0, 0));
		// set bottom position and width
		borders.getImage(GlobalConstants.CORNER_01BOTTOM).setWidth(
				width - imgBL.getWidth() - imgBR.getWidth());
		borders.getImage(GlobalConstants.CORNER_01BOTTOM).setPosition(
				new SimpleVector3(imgBL.getWidth(), 0, 0));
		// set bottom-right position
		borders.getImage(GlobalConstants.CORNER_02BOTTOM_RIGHT)
				.setPosition(
						new SimpleVector3(width - imgBR.getWidth(), 0, 0));
		// set left position and height
		borders.getImage(GlobalConstants.CORNER_03LEFT).setHeight(
				height - imgBL.getHeight() - imgTL.getHeight());
		borders.getImage(GlobalConstants.CORNER_03LEFT).setPosition(
				new SimpleVector3(0, imgBL.getHeight(), 0));
		// set right position and height
		borders.getImage(GlobalConstants.CORNER_04RIGHT).setHeight(
				height - imgBR.getHeight() - imgTR.getHeight());
		borders.getImage(GlobalConstants.CORNER_04RIGHT).setPosition(
				new SimpleVector3(width - imgR.getWidth(), imgBR
						.getHeight(), 0));
		// set top-left position
		borders.getImage(GlobalConstants.CORNER_05TOP_LEFT).setPosition(
				new SimpleVector3(0, height - imgTL.getHeight(), 0));
		// set top position and width
		borders.getImage(GlobalConstants.CORNER_06TOP).setWidth(
				width - imgTL.getWidth() - imgTR.getWidth());
		borders.getImage(GlobalConstants.CORNER_06TOP)
				.setPosition(
						new SimpleVector3(imgTL.getWidth(), height
								- imgT.getHeight(), 0));
		// set top-right position
		borders.getImage(GlobalConstants.CORNER_07TOP_RIGHT).setPosition(
				new SimpleVector3(width - imgTR.getWidth(),
						height - imgTR.getHeight(), 0));
		// clear local variables
		imgTL = null;
		imgT = null;
		imgTR = null;
		imgR = null;
		imgBL = null;
		imgBR = null;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void prepareForRendering() throws Exception {
		if (super.isDebug()) {
			middle.setDebug(true);
		}
		Render.getInstance().registerEntity(borders);
		Render.getInstance().registerEntity(middleImages);
		Render.getInstance().registerEntity(middle);
	}
	/**
	 * Sets the border images used.
	 * @param corners the list of border images
	 * @throws Exception if an error occurs
	 */
	private void setBorders(final String[] corners) throws Exception {
		SpriteImageObject imgBL =
				SpriteImageObjectFactory.getInstance().getImageByName(
						corners[GlobalConstants.CORNER_00BOTTOM_LEFT]);
		SpriteImageObject imgB =
				SpriteImageObjectFactory.getInstance().getImageByName(
						corners[GlobalConstants.CORNER_01BOTTOM]);
		SpriteImageObject imgBR =
				SpriteImageObjectFactory.getInstance().getImageByName(
						corners[GlobalConstants.CORNER_02BOTTOM_RIGHT]);
		SpriteImageObject imgTL =
				SpriteImageObjectFactory.getInstance().getImageByName(
						corners[GlobalConstants.CORNER_05TOP_LEFT]);
		SpriteImageObject imgTR =
				SpriteImageObjectFactory.getInstance().getImageByName(
						corners[GlobalConstants.CORNER_07TOP_RIGHT]);
		SpriteImageObject imgT =
				SpriteImageObjectFactory.getInstance().getImageByName(
						corners[GlobalConstants.CORNER_06TOP]);
		SpriteImageObject imgL =
				SpriteImageObjectFactory.getInstance().getImageByName(
						corners[GlobalConstants.CORNER_03LEFT]);
		SpriteImageObject imgR =
				SpriteImageObjectFactory.getInstance().getImageByName(
						corners[GlobalConstants.CORNER_04RIGHT]);
		borders = new GroupOfImages();
		// bottom left
		BasicSpriteObject sb = new BasicSpriteObject();
		sb.setImageRefId(imgBL.getRefId());
		sb.setWidth(imgBL.getWidth());
		sb.setHeight(imgBL.getHeight());
		borders.addImage(sb);
		// bottom middle
		sb = new BasicSpriteObject();
		sb.setImageRefId(imgB.getRefId());
		sb.setHeight(imgB.getHeight());
		borders.addImage(sb);
		// bottom right
		sb = new BasicSpriteObject();
		sb.setImageRefId(imgBR.getRefId());
		sb.setWidth(imgBR.getWidth());
		sb.setHeight(imgBR.getHeight());
		borders.addImage(sb);
		// left
		sb = new BasicSpriteObject();
		sb.setImageRefId(imgL.getRefId());
		sb.setWidth(imgL.getWidth());
		borders.addImage(sb);
		// right
		sb = new BasicSpriteObject();
		sb.setImageRefId(imgR.getRefId());
		sb.setWidth(imgR.getWidth());
		borders.addImage(sb);
		// top left
		sb = new BasicSpriteObject();
		sb.setImageRefId(imgTL.getRefId());
		sb.setWidth(imgTL.getWidth());
		sb.setHeight(imgTL.getHeight());
		borders.addImage(sb);
		// top middle
		sb = new BasicSpriteObject();
		sb.setImageRefId(imgT.getRefId());
		sb.setHeight(imgT.getHeight());
		borders.addImage(sb);
		// top right
		sb = new BasicSpriteObject();
		sb.setImageRefId(imgTR.getRefId());
		sb.setWidth(imgTR.getWidth());
		sb.setHeight(imgTR.getHeight());
		borders.addImage(sb);
		// clear local variables
		sb = null;
		imgTL = null;
		imgT = null;
		imgTR = null;
		imgL = null;
		imgR = null;
		imgBL = null;
		imgB = null;
		imgBR = null;
	}
	/**
	 * Sets the background images used.
	 * @param middleSet the list of background images
	 * @throws Exception if an error occurs
	 */
	private void setMiddleImages(final String[] middleSet) throws Exception {
		SpriteImageObject imgBL =
				SpriteImageObjectFactory.getInstance().getImageByName(
						middleSet[GlobalConstants.CORNER_00BOTTOM_LEFT]);
		SpriteImageObject imgBR =
				SpriteImageObjectFactory.getInstance().getImageByName(
						middleSet[GlobalConstants.CORNER_02BOTTOM_RIGHT]);
		SpriteImageObject imgTL =
				SpriteImageObjectFactory.getInstance().getImageByName(
						middleSet[GlobalConstants.CORNER_05TOP_LEFT]);
		SpriteImageObject imgTR =
				SpriteImageObjectFactory.getInstance().getImageByName(
						middleSet[GlobalConstants.CORNER_07TOP_RIGHT]);
		middleImages = new GroupOfImages();
		// bottom left
		BasicSpriteObject sb = new BasicSpriteObject();
		sb.setImageRefId(imgBL.getRefId());
		sb.setWidth(imgBL.getWidth());
		sb.setHeight(imgBL.getHeight());
		middleImages.addImage(sb);
		// bottom right
		sb = new BasicSpriteObject();
		sb.setImageRefId(imgBR.getRefId());
		sb.setWidth(imgBR.getWidth());
		sb.setHeight(imgBR.getHeight());
		middleImages.addImage(sb);
		// top left
		sb = new BasicSpriteObject();
		sb.setImageRefId(imgTL.getRefId());
		sb.setWidth(imgTL.getWidth());
		sb.setHeight(imgTL.getHeight());
		middleImages.addImage(sb);
		// top right
		sb = new BasicSpriteObject();
		sb.setImageRefId(imgTR.getRefId());
		sb.setWidth(imgTR.getWidth());
		sb.setHeight(imgTR.getHeight());
		middleImages.addImage(sb);
		// clear local variables
		sb = null;
		imgTL = null;
		imgTR = null;
		imgBL = null;
		imgBR = null;
	}
	/**
	 * Sets the size and position for all middle background images.
	 * @param width the border's width
	 * @param height the border's height
	 * @throws Exception if an error occurs
	 */
	private void setMiddleImageSizes(final int width, final int height)
			throws Exception {
		int w = width, h = height;
		int leftOffset = 0, rightOffset = 0, bottomOffset = 0, topOffset = 0;
		if (useOffsets) {
			w -= middleInsetX * 2;
			h -= middleInsetY * 2;
			leftOffset = middleInsetX;
			rightOffset = middleInsetX;
			bottomOffset = middleInsetY;
			topOffset = middleInsetY;
		} else {
			SpriteImageObject img =
					SpriteImageObjectFactory.getInstance().getImageById(
							borders.getImage(GlobalConstants.CORNER_03LEFT)
									.getImageRefId());
			w -= img.getWidth();
			leftOffset = img.getWidth();
			img = SpriteImageObjectFactory.getInstance().getImageById(
					borders.getImage(GlobalConstants.CORNER_04RIGHT)
							.getImageRefId());
			w -= img.getWidth();
			rightOffset = img.getWidth();

			img = SpriteImageObjectFactory.getInstance().getImageById(
					borders.getImage(
							GlobalConstants.CORNER_01BOTTOM)
							.getImageRefId());
			h -= img.getHeight();
			bottomOffset = img.getHeight();
			img = SpriteImageObjectFactory.getInstance().getImageById(
					borders.getImage(
							GlobalConstants.CORNER_06TOP)
							.getImageRefId());
			h -= img.getHeight();
			topOffset = img.getHeight();
		}
		SpriteImageObject imgBL =
				SpriteImageObjectFactory.getInstance().getImageById(
						middleImages.getImage(0).getImageRefId()
						);
		SpriteImageObject imgBR =
				SpriteImageObjectFactory.getInstance().getImageById(
						middleImages.getImage(1).getImageRefId()
						);
		SpriteImageObject imgTL =
				SpriteImageObjectFactory.getInstance().getImageById(
						middleImages.getImage(2).getImageRefId()
						);
		SpriteImageObject imgTR =
				SpriteImageObjectFactory.getInstance().getImageById(
						middleImages.getImage(GlobalConstants.INT_003)
								.getImageRefId()
						);

		int spriteBLW = imgBL.getWidth(), spriteBLH = imgBL.getHeight();
		int spriteBRW = imgBR.getWidth(), spriteBRH = imgBR.getHeight();
		int spriteTLW = imgTL.getWidth(), spriteTLH = imgTL.getHeight();
		int spriteTRW = imgTR.getWidth(), spriteTRH = imgTR.getHeight();
		// do any images need to be partially-rendered?
		if (imgBL.getWidth() + imgBR.getWidth() > w) {
			// bottom images need width crop
			// see if left is less than w/2
			if (spriteBLW <= w / 2) {
				// bottom-left width is okay, bottom-right should be cropped
				spriteBRW = w - spriteBLW;
			} else if (spriteBRW <= w / 2) {
				// bottom-right width is okay, bottom-left should be cropped
				spriteBLW = w - spriteBRW;
			} else {
				spriteBLW = w / 2;
				spriteBRW = w / 2;
			}
		}
		if (imgTL.getWidth() + imgTR.getWidth() > w) {
			// top images need width crop
			// see if left is less than w/2
			if (spriteTLW <= w / 2) {
				// top-left width is okay, top-right should be cropped
				spriteTRW = w - spriteTLW;
			} else if (spriteTRW <= w / 2) {
				// top-right width is okay, top-left should be cropped
				spriteTLW = w - spriteTRW;
			} else {
				spriteTLW = w / 2;
				spriteTRW = w / 2;
			}
		}
		if (imgBL.getHeight() + imgTL.getHeight() > h) {
			// left images need height crop
			// see if bottom is less than h/2
			if (spriteBLH <= h / 2) {
				// bottom-left height is okay, top-left should be cropped
				spriteTLH = h - spriteBLH;
			} else if (spriteTLH <= h / 2) {
				// top-left height is okay, bottom-left should be cropped
				spriteBLH = h - spriteTLH;
			} else {
				spriteBLH = h / 2;
				spriteTLH = h / 2;
			}
		}
		if (imgBR.getHeight() + imgTR.getHeight() > h) {
			// right images need height crop
			// see if bottom is less than h/2
			if (spriteBRH <= h / 2) {
				// bottom-right height is okay, top-right should be cropped
				spriteTRH = h - spriteBRH;
			} else if (spriteTRH <= h / 2) {
				// top-right height is okay, bottom-right should be cropped
				spriteBRH = h - spriteTRH;
			} else {
				spriteBRH = h / 2;
				spriteTRH = h / 2;
			}
		}
		// set bottom-left position and render modifications
		SpriteBase sb = middleImages.getImage(0);
		sb.setPosition(new SimpleVector3(leftOffset, bottomOffset, 0));
		Sprite.getInstance().setPartiallyRendered(
				sb,
				sb.getPosition().getY() + imgBL.getHeight(), // sprite's top y
				sb.getPosition().getX(), // sprite's left x
				sb.getPosition().getY(), // sprite's bottom y
				sb.getPosition().getX() + imgBL.getWidth(), // sprite's right x
				sb.getPosition().getY() + spriteBLH, // bounding-box top
				// cropping starts from top
				sb.getPosition().getX(), // bounding-box left
				sb.getPosition().getY(), // bounding-box bottom
				sb.getPosition().getX() + spriteBLW // bounding-box right
				// crop from right
		);
		// set bottom-right position and render modifications
		sb = middleImages.getImage(1);
		sb.setPosition(new SimpleVector3(
				width - rightOffset - imgBR.getWidth(),
				bottomOffset,
				0));
		Sprite.getInstance().setPartiallyRendered(
				sb,
				sb.getPosition().getY() + imgBR.getHeight(), // sprite's top y
				sb.getPosition().getX(), // sprite's left x
				sb.getPosition().getY(), // sprite's bottom y
				sb.getPosition().getX() + imgBR.getWidth(), // sprite's right x
				sb.getPosition().getY() + spriteBRH, // bounding-box top
				// crop from top
				sb.getPosition().getX() + (imgBR.getWidth() - spriteBRW), 
				// bounding-box left
				// crop from left
				sb.getPosition().getY(), // bounding-box bottom
				sb.getPosition().getX() + imgBR.getWidth() // bounding-box right
		);
		// set top-left position and render modifications
		sb = middleImages.getImage(2);
		sb.setPosition(new SimpleVector3(
				leftOffset,
				height - topOffset - imgTL.getHeight(),
				0));
		Sprite.getInstance().setPartiallyRendered(
				sb,
				sb.getPosition().getY() + imgTL.getHeight(), // sprite's top y
				sb.getPosition().getX(), // sprite's left x
				sb.getPosition().getY(), // sprite's bottom y
				sb.getPosition().getX() + imgTL.getWidth(), // sprite's right x
				sb.getPosition().getY() + imgTL.getHeight(), // bounding-box top
				// top should always be where top would be without crop.
				// cropping should start from bottom
				sb.getPosition().getX(), // bounding-box left
				sb.getPosition().getY() + (imgTL.getHeight() - spriteTLH), 
				// bounding-box bottom
				// crop from bottom
				sb.getPosition().getX() + spriteTLW // bounding-box right
				// crop from right
		);
		// set top-right position and render modifications
		sb = middleImages.getImage(GlobalConstants.INT_003);
		sb.setPosition(new SimpleVector3(
				width - rightOffset - imgTR.getWidth(),
				height - topOffset - imgTR.getHeight(),
				0));
		Sprite.getInstance().setPartiallyRendered(
				sb,
				sb.getPosition().getY() + imgTR.getHeight(), // sprite's top y
				sb.getPosition().getX(), // sprite's left x
				sb.getPosition().getY(), // sprite's bottom y
				sb.getPosition().getX() + imgTR.getWidth(), // sprite's right x
				sb.getPosition().getY() + imgTR.getHeight(), // bounding-box top
				sb.getPosition().getX() + (imgTR.getWidth() - spriteTRW), 
				// bounding-box left
				// crop from left
				sb.getPosition().getY() + (imgTR.getHeight() - spriteTRH), 
				// bounding-box bottom
				// crop from bottom
				sb.getPosition().getX() + imgTR.getWidth() // bounding-box right
		);

		sb = null;
		imgBL = null;
		imgBR = null;
		imgTL = null;
		imgTR = null;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void setPosition(final double x, final double y,
			final double z) {
		final float edgeLevel = 0.0002f, backgroundLevel = 0.0001f;
		super.setPosition(x, y, z);
		borders.setPosition(x, y, z + GlobalConstants.CHILD_STEP * edgeLevel);
		borders.clearFloatStore();
		middleImages.setPosition(x, y, 
				z + GlobalConstants.CHILD_STEP * backgroundLevel);
		middleImages.clearFloatStore();
		middle.setPosition(x + middleInsetX, y + middleInsetY, z);
		middle.clearFloatStore();
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void setPreferredSize(final int width, final int height) {
		super.setPreferredSize(width, height);
		final float edgeLevel = 0.0002f, backgroundLevel = 0.0001f;
		try {
			positionBorders(width, height);
			setMiddleImageSizes(width, height);
			// set middle position and width
			if (useOffsets) {
				middle.setWidth(width - middleInsetX * 2);
				middle.setHeight(height - middleInsetY * 2);
			} else {
				int offset = 0;
				SpriteImageObject img =
						SpriteImageObjectFactory.getInstance().getImageById(
								borders.getImage(GlobalConstants.CORNER_03LEFT)
										.getImageRefId());
				offset += img.getWidth();
				img = SpriteImageObjectFactory.getInstance().getImageById(
						borders.getImage(GlobalConstants.CORNER_04RIGHT)
								.getImageRefId());
				offset += img.getWidth();
				middle.setWidth(width - offset);

				offset = 0;
				img = SpriteImageObjectFactory.getInstance().getImageById(
						borders.getImage(
								GlobalConstants.CORNER_01BOTTOM)
								.getImageRefId());
				offset += img.getHeight();
				img = SpriteImageObjectFactory.getInstance().getImageById(
						borders.getImage(GlobalConstants.CORNER_06TOP)
								.getImageRefId());
				offset += img.getHeight();
				middle.setHeight(height - offset);
				img = null;
			}
			if (super.getPosition() != null) {
				borders.setPosition(
						super.getPosition().getX(),
						super.getPosition().getY(),
						super.getPosition().getZ()
								+ GlobalConstants.CHILD_STEP * edgeLevel
						);
				borders.clearFloatStore();
				middleImages.setPosition(
						super.getPosition().getX(),
						super.getPosition().getY(),
						super.getPosition().getZ()
								+ GlobalConstants.CHILD_STEP * backgroundLevel
						);
				middleImages.clearFloatStore();
				middle.setPosition(
						super.getPosition().getX() + middleInsetX,
						super.getPosition().getY() + middleInsetY,
						super.getPosition().getZ()
						);
				middle.clearFloatStore();
			}
		} catch (Exception ex) {
			JOGLErrorHandler.getInstance().fatalError(ex);
		}
	}
}
